import can
import time
import threading

import datetime

from Test import VirtualCANBus

# 配置CAN接口（根据系统调整）
bus = can.interface.Bus(channel='virtual_can0', bustype='virtual')

# 要发送的CAN消息配置
can_msg = can.Message(
    arbitration_id=0x123,  # CAN ID (十六进制)
    data=[0x01, 0x02, 0x03, 0x04],  # 数据（8字节以内）
    is_extended_id=False  # 标准帧
)

# 创建停止发送事件的标志
stop_event = threading.Event()


def get_timestamp():
    """获取当前时间戳（毫秒精度）"""
    return datetime.datetime.now().strftime('%H:%M:%S.%f')[:-3]


def cyclic_send_task(interval_ms=20):
    """定时发送CAN消息的任务"""
    while not stop_event.is_set():
        start_time = time.perf_counter()

        try:
            bus.send(can_msg)
            print(f"发送: {can_msg} | 时间: {get_timestamp()}")
        except can.CanError as e:
            print(f"发送失败: {e}")

        # 精确时间控制
        elapsed = (time.perf_counter() - start_time) * 1000  # 转换为毫秒
        sleep_time = max(0, interval_ms - elapsed) / 1000.0

        if sleep_time > 0:
            time.sleep(sleep_time)


def receive_messages():
    """接收CAN消息的任务"""
    try:
        while not stop_event.is_set():
            response = bus.recv(timeout=0.1)  # 100ms超时
            if response is not None:
                print(f"收到: {response} | 时间: {get_timestamp()}")
    except KeyboardInterrupt:
        stop_event.set()


if __name__ == "__main__":
    # 创建虚拟CAN总线
    #引入测试用例
    can_bus = VirtualCANBus()
    can_bus.start()
    try:
        # 提高Windows定时精度（可选）
        try:
            import win32api

            win32api.timeBeginPeriod(1)
            print("已设置1ms定时精度")
        except ImportError:
            print("未安装pywin32，定时精度可能受限")

        # 创建并启动发送线程
        send_thread = threading.Thread(
            target=cyclic_send_task,
            args=(20,),  # 20ms间隔
            daemon=True
        )
        send_thread.start()

        # 在主线程中接收消息
        print("开始虚拟CAN通信 (Ctrl+C停止)...")
        receive_messages()

    except KeyboardInterrupt:
        print("\n程序终止")
    finally:
        stop_event.set()
        if send_thread.is_alive():
            send_thread.join(timeout=1.0)
        bus.shutdown()

        # 恢复Windows定时精度（如果修改过）
        try:
            import win32api

            win32api.timeEndPeriod(1)
        except ImportError:
            pass

        print("资源已释放")